package ihm.panel.file;

import ihm.applet.KrakenApplet;

import ihm.panel.PanelInterface;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;

import tools.AppletConstant;
import tools.PasswordSecurity;
import tools.StringUtils;

import bdd.sql.server.bean.User;

/**
 * Affiche le panneau de login.
 * @author Guillaume Pocas & Jean-Fraçois Augé
 */
public class LoginPanel extends JPanel implements ActionListener, PanelInterface {

	private static final long serialVersionUID = 1L;
	private JLabel connect_jl, login_jl, password_jl;
	private JTextField login_jtf, password_jtf, seed_jtf;
	private JButton connect_jb;
	private KrakenApplet applet;

	/**
	 * Constructeur.
	 * @param app
	 */
	public LoginPanel(KrakenApplet app) {
		this.applet = app;
		this.initPanel();
		this.initActions();
	}

	@Override
	public void initPanel() {
		this.setLayout(new GridBagLayout());
		GridBagConstraints constraints = new GridBagConstraints();

		connect_jl = new JLabel("Veuillez vous connecter");

		login_jl = new JLabel("Login : ");

		password_jl = new JLabel("Mot de passe : ");

		login_jtf = new JTextField("admin");
		login_jtf.setPreferredSize(AppletConstant.FIELD_SIZE);

		password_jtf = new JPasswordField("admin");
		password_jtf.setPreferredSize(AppletConstant.FIELD_SIZE);
		
		//seed_jtf = new JTextField("graine");
		//seed_jtf.setPreferredSize(AppletConstant.FIELD_SIZE);
		
		connect_jb = new JButton("Connexion");
		connect_jb.setPreferredSize(AppletConstant.BUTTON_SIZE);

		constraints.insets = new Insets(AppletConstant.BUTTON_INSET,
				AppletConstant.BUTTON_INSET,
				AppletConstant.BUTTON_INSET,
				AppletConstant.BUTTON_INSET);

		constraints.gridx = 0;
		constraints.gridy = 0;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.anchor = GridBagConstraints.NORTH;
		constraints.fill = GridBagConstraints.NONE;
		add(connect_jl, constraints);

		constraints.gridx = 1;									// position en x
		constraints.gridy = 1;									// position en y
		constraints.gridwidth = GridBagConstraints.REMAINDER;	// largeur de l'object en nombre de case, ici le reste de la ligne
		constraints.anchor = GridBagConstraints.EAST;			// l'ancrage de l'object
		constraints.fill = GridBagConstraints.NONE;				// est ce que l'object prend toute la case?
		add(login_jtf, constraints);

		constraints.gridx = 1;
		constraints.gridy = 2;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.EAST;
		constraints.fill = GridBagConstraints.NONE;
		add(password_jtf, constraints);

		constraints.gridx = 0;
		constraints.gridy = 1;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.anchor = GridBagConstraints.WEST;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		add(login_jl, constraints);

		constraints.gridx = 0;
		constraints.gridy = 2;
		constraints.gridwidth = 1;
		constraints.anchor = GridBagConstraints.WEST;
		constraints.fill = GridBagConstraints.HORIZONTAL;
		add(password_jl, constraints);

		constraints.gridx = 0;
		constraints.gridy = 3;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.anchor = GridBagConstraints.SOUTH;
		constraints.fill = GridBagConstraints.NONE;
		add(connect_jb, constraints);
		
		/*constraints.gridx = 0;
		constraints.gridy = 4;
		constraints.gridwidth = GridBagConstraints.REMAINDER;
		constraints.anchor = GridBagConstraints.SOUTH;
		constraints.fill = GridBagConstraints.NONE;
		add(seed_jtf, constraints);*/
	}

	/**
	 * Initialise les actions.
	 */
	public void initActions() {
		connect_jb.addActionListener(this);
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if(e.getSource().equals(connect_jb)) {
			//verif remplissage des champs
			if(this.login_jtf.getText().isEmpty() || this.password_jtf.getText().isEmpty()) {
				//lancer un pop up d'erreur
				JOptionPane.showMessageDialog(this,
						"Veuillez remplir les champs Login et Mot de passe !", 
						"Champs non remplis", 
						JOptionPane.INFORMATION_MESSAGE );
			}
			else {
				Session session = applet.getSession();
				@SuppressWarnings("unchecked")
				List<User> resultats = session.createCriteria(User.class).add(Restrictions.eq("user_mail", login_jtf.getText())).list();

				if(resultats.size() == 0) {
					JOptionPane.showMessageDialog(this,
							"Les identifiants ne sont pas reconnus : vérifier les informations saisies.",
							"Erreur de login",
							JOptionPane.ERROR_MESSAGE);
				}
				else {
					for(int i = 0; i<resultats.size(); i++) {
						User u = resultats.get(i);
						
						/*byte[] test = PasswordSecurity.sha256_2("admin", "?myehz%Ga!eQ");
						String db = StringUtils.bytesToString(test);
						System.out.println(db);
						
						String pwd_input = password_jtf.getText();
						String hash = StringUtils.bytesToString((PasswordSecurity.sha256_2("admin", "?myehz%Ga!eQ")));
						//String hash = PasswordSecurity.sha256_2("admin", "A.[8$lr}hlf^");
						byte[] hash2 = PasswordSecurity.sha256_2("admin", "?myehz%Ga!eQ");
						String hashToLongString = StringUtils.bytesToString(hash.getBytes());
						String hashToLongString2 = StringUtils.bytesToString(hash2);
						
						System.out.println("mdp : "+u.getUser_pwd());
						System.out.println("mdpToBytes : "+new String(StringUtils.stringToBytes(u.getUser_pwd())));
						System.out.println("graine : "+u.getUser_seedPwd());
						System.out.println("longueur_graine : "+u.getUser_seedPwd().length()+"\n");
						System.out.println("longueur_graine2 : "+seed_jtf.getText().length()+"\n");

						System.out.println("champMdp :"+pwd_input);
						System.out.println("hash :"+hash);
						System.out.println("hash2 :"+hash2);
						System.out.println("hashToLongString :"+hashToLongString);
						System.out.println("hashToLongString2 :"+hashToLongString2+"\n");
						
						System.out.println("comparaison des strings "+u.getUser_pwd().equals(hashToLongString));
						System.out.println("comparaison des bytes "+Arrays.equals(StringUtils.stringToBytes(u.getUser_pwd()), hash.getBytes()));
						System.out.println("comparaison des graines "+u.getUser_seedPwd().equals(seed_jtf.getText())+"\n");
						
						System.out.println("comparaison des strings2 "+u.getUser_pwd().equals(hash));*/

						/*System.out.println("default charset "+Charset.defaultCharset().toString());
						byte[] test = PasswordSecurity.sha256_2("admin", "aaaaaaaaaaaa");
						byte[] test1 = PasswordSecurity.sha256("admin", "aaaaaaaaaaaa");
						String b64 = StringUtils.toBase64(test);
						String b64_ = StringUtils.toBase64(test1);
						System.out.println(" >>> "+b64);
						System.out.println(" >>> "+b64_);*/
						
						String pwd_input = password_jtf.getText();
						byte[] hash = PasswordSecurity.sha256_2(pwd_input, u.getUser_seedPwd());
						String b64 = StringUtils.toBase64(hash);
						System.out.println("pass "+pwd_input);
						System.out.println("seed "+u.getUser_seedPwd());
						System.out.println("hash "+b64);
						
						//if(u.getYes_pwd().equals(password_jtf.getText())) {
						if(u.getUser_pwd().equals(b64)) {
									//premiere connexion
							if(resultats.get(i).getUser_firstcon() == 1) {
								
								//applet.setUser(resultats.get(i));
								applet.setUser_ID(resultats.get(i).getUser_id());
								
								new ChangePassword(applet);
								applet.setPanel("Login");
								login_jtf.setText("");
								password_jtf.setText("");
							}
							else {
								login_jtf.setText("");
								password_jtf.setText("");
								applet.connect(resultats.get(i).getUser_id());
							}
						}
						else {
							JOptionPane.showMessageDialog(this, 
									"Le mot de passe saisi pour cet identifiant n'est pas valide.", 
									"Erreur de login", 
									JOptionPane.ERROR_MESSAGE );
						}
					}
					session.close();
				}
			}
		}
	}

}
